/* -*- Mode:Prolog; coding:ISO-8859-1; -*- */
:- multifile saved_solution/3, saved_best_solution/3.
:- dynamic saved_solution/3, terminate/1, saved_best_solution/3.


select_positives(Examples, Positives, NP) :-
        (Examples \= [] ->
        findall(example(An,Bn), 
                (
                   member(example(An, Bn), Examples), Bn > 0
                ),
               Positives),
        length(Positives, NP)
        ;
        NP = 0
        ).


number_positives(Examples, NP) :-
        (Examples \= [] ->
        findall(example(An,Bn), 
                (
                   member(out_example(An, Bn, _Provn), Examples), Bn > 0
                ),
               Positives),
        length(Positives, NP)
        ;
        NP = 0
        ).

number_negatives(Examples, NN) :-
        (Examples \= [] ->
        findall(example(An,Bn), 
                (
                   member(out_example(An, Bn, _Provn), Examples), Bn < 0
                ),
               Negatives),
        length(Negatives, NN)
        ;
        NN = 0
        ).

entailed_positives(Examples, EP) :-
        (Examples \= [] ->
        findall(example(An,Bn), 
                (
                   member(out_example(An, Bn, Provn), Examples), Bn > 0, Provn > 0
                ),
               EntailedPositives),
        length(EntailedPositives, EP)
        ;
        EP = 0
        ).


entailed_negatives(Examples, EN) :-
        (Examples \= [] ->
        findall(example(An,Bn), 
                (
                   member(out_example(An, Bn, Provn), Examples), Bn < 0, Provn > 0
                ),
               EntailedNegatives),
        length(EntailedNegatives, EN)
        ;
        EN = 0
        ).


unentailedEx(Examples, UnentailedExamples) :-
        (Examples \= [] ->
        findall(example(An,Bn), 
                (
                   member(out_example(An, Bn, Provn), Examples), Provn < 0
                ),
               UnentailedExamples)        
        ;
        UnentailedExamples = []
        ).

complexity([], 0).
complexity([H | T], S) :- %print('r'), print([H | T]), nl,
        rule_complexity(H, RS),
        complexity(T, SO),
        S is SO + RS.

rule_complexity((_ :- B), RS) :- %print('h'),
        body_complexity(B, RSB),
        RS is RSB + 1.

body_complexity((_H, T), RS) :- !, %print('b'), 
        body_complexity(T, RSO),
        RS is RSO + 1.

body_complexity(true, 0) :- !.
body_complexity(_, 1) :- %print('a'), 
                         !.



%save_solution(Solution, Info, Score) :-
%        saved_solution(_SolutionSaved, _, ScoreSaved), !,
%        (Score < ScoreSaved ->
%                retractall(saved_solution(_,_, _)),
%                assert(saved_solution(Solution,Info, Score)),
%                log('################Best solution################')
%        ;
%         Score = ScoreSaved ->
%                assert(saved_solution(Solution, Info, Score))
%         ;
%                true
%        ),
%        findall((Solutionx, Scorex), saved_solution(Solutionx, _, Scorex), Solutionsx), 
%        (termination(Solutionsx) ->
%                finalise_learning(Solutionsx),
%                halt
%         ;                     
%                true    
%        ).
        
save_solution(Solution, _, _) :-
        saved_solution(Solution, _Info, _Score),
        print(Solution),
        print(Info),
        print('it is saved'), !.

save_solution(Solution, Info, Score) :-
        %Suppose score is -2
        saved_solution(_SolutionSaved, _, _ScoreSaved), !,
        %Suppose scores are [-4, 3, -1, 10] (-4 is the best)
        findall(InvSC-(saved_solution(Solutionx, Infox, Scorex)), (saved_solution(Solutionx, Infox, Scorex), InvSC is -Scorex), ASC),
        %In the list we get [4, -3, 1, -10] (4 is the best)
        sort(ASC, [WorstScore-(ToRetract) | TSolutionsx]),
        %Now sorted In the list we get [-10, -3, 1, 4] (4 is the best)
%        portray_list([WorstScore-(ToRetract) | TSolutionsx]),
        bb_get_value(solution_pool, SP),
        ScoreInv is -Score,
        %ScoreInv is 2
        length(TSolutionsx, LCS), LCST is LCS + 1,
        ((\+ var(ScoreInv), \+ var(WorstScore), ScoreInv  < WorstScore) ->              %The current score is worse than the worst saved (2 < -10)
                (LCST < SP ->                   %But there's room in the pool
                         assert(saved_solution(Solution,Info, Score))
                ;
                         true
                )
        ;                                       %The current score is better than the worst saved
                (LCST >= SP ->   
                        retract(ToRetract)
                        ;
                        true
                ),
                assert(saved_solution(Solution,Info, Score)),
                reverse([WorstScore-(ToRetract) | TSolutionsx], [InvBestScore-_ | _]),
                %InvBestScore is 4
                BestScore is (-1) * InvBestScore,
                %BestScore is -4
                (Score < BestScore ->        
                 log('################Best solution################'),
                 retractall(saved_best_solution(_Solution,_Info, _Score)),
                 assert(saved_best_solution(Solution,Info, Score))
                ;
                 true)
        ),
        findall((Solutionxxx, Scorexxx), saved_solution(Solutionxxx, _, Scorexxx), Solutionsxxx), 
        (termination(Solutionsxxx) ->
                finalise_learning(Solutionsxxx),
                assert(terminate(Solutionsxxx))
         ;                     
                true    
        ).

         
save_solution(Solution, Info, Score) :-         
        assert(saved_solution(Solution, Info, Score)),
        assert(saved_best_solution(Solution,Info, Score)).    
        
get_best_solution(SolutionBest, InfoBest, ScoreBest) :- 
        saved_best_solution(SolutionBest, InfoBest, ScoreBest), !.



make_output_file :-
        findall(solution(Score,Solution), saved_solution(Solution, _Info, Score), Solutions),
        sort(Solutions , SSol),
        list_to_file(SSol, '../temp/solution.txt').

print_solutions([]).
print_solutions([(H, S) | T]) :-
        portray_list(H),
        print('With score '), print(S), nl,
        log('- - - - - - - -'),
        print_solutions(T).